#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<string.h>

#include<iostream>
#include<vector>
#include<unordered_map>
#include<functional>
namespace prosPoolNameSpace{
    const int BUFFER_SIZE = 1024;
}

class processPool
{
private:
    int _process_num;
    std::unordered_map<pid_t,int(*)[2]>_pipe_childs;
    std::unordered_map<pid_t,bool>_childs_state;
    std::vector<std::function<void*(void*)>>_funcs;
public:
    processPool(int num = 5);
    ~processPool();
    void funcAdd(std::function<void*(void*)>);
    void runFunc(int pos);
};


processPool::processPool(int num) : _process_num(num)
{
    if(num <= 0){
        
        perror("process pool num <= 0 is invaild");
        throw std::invalid_argument("process pool create fail");
    }
    int pipfd[2];
    for(int i = 0;i < num;i++){
        char buffer[prosPoolNameSpace::BUFFER_SIZE] = {0};
        if(pipe(pipfd) == -1){
            perror("pipfid");
            throw std::runtime_error("pipe create fail");
        }

        pid_t pipe_child = fork();
        if(pipe_child == -1){
            perror("fork");
            throw std::runtime_error("fork fail");
        }
        else if(pipe_child == 0){
            close(pipfd[1]);
            while(1){
                pid_t myid = getpid();
                buffer[0] = 0;
                ssize_t n = read(pipfd[0],buffer,sizeof(buffer));
                if(n > 1 || n == -1){
                    perror("read");
                    throw std::runtime_error("read fail");
                }
                else if(!n){printf("write side close ,process%d exit\n",myid);break;}
                int state_num = buffer[0] - '0';
                std::cout << "get a state_num:" << state_num << "task start" << std::endl;
                _funcs[state_num];   
                std::cout << "process:" << getpid() << "-fininsh task:" << state_num  << std::endl;
                _childs_state[myid] = false;
            }
            close(pipfd[0]);
        }   
        else{
            _pipe_childs.emplace(pipe_child,&pipfd);
            _childs_state.emplace(pipe_child,false);
        }
    }
}

processPool::~processPool()
{
    ;
}

void processPool::funcAdd(std::function<void*(void*)>func){
    _funcs.push_back(func);
}

void processPool::runFunc(int pos){
    if(pos >= _funcs.size()){throw std::invalid_argument("pos is invaild");}
    auto idle_pid = _childs_state.begin();
    while(idle_pid->second){
        printf("process%d is busy\n",idle_pid->first);
        idle_pid++;
        if(idle_pid == _childs_state.end())idle_pid = _childs_state.begin();
    }
    pid_t pipe_child = idle_pid->first;
    int (*pipefd)[2] = _pipe_childs[pipe_child];
    close(*pipefd[0]);
    write(*pipefd[1],&pos,sizeof(int));
    idle_pid->second = false;
    printf("successfully send message to process%d\n",pipe_child);
    
}




















// #include <iostream>
// #include <vector>
// #include <functional>

// // 定义一个普通函数
// int add(int a, int b) {
//     return a + b;
// }

// int main() {
//     // 声明存储可调用对象的向量
//     std::vector<std::function<int(int, int)>> func;
//     // 添加可调用对象到向量
//     func.push_back(add);

//     int result = func[0](3, 4);
//     std::cout << "调用存储的函数结果: " << result << std::endl;

//     return 0;
// }